package com.tech.koufu.action;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.DbUtils.DaoConfig;
import com.lidroid.xutils.db.sqlite.Selector;
import com.tech.koufu.MyApplication;
import com.tech.koufu.model.Stock;
import com.tech.koufu.tools.DiskLruCache;
import com.tech.koufu.tools.KouFuTools;
import com.tech.koufu.tools.Statics;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Handler;
import android.text.format.DateFormat;
import android.util.Log;

/**
 * 股票下载，缓存，读取，xml 解析
 * 
 * @author jl_luo
 *
 */
public class StockManager {
	private static final String TAG = "StockManager";
	public static final String STOCKS_FILENAME = "stocks";
	public static final String STOCKS_DBNAME = "cofools";
	public static final String KEY_HASNEWEST = "key_hasnewest";
	public static final long DISK_CACHE_SIZE = 2 * 1024 * 1024;
	private Context context;
	private RequestQueue mQueue;
	private MyApplication myApplication;
	DiskLruCache mDiskLruCache = null;
	public ArrayList<Stock> stockInfos;
	private Handler handler;
	StringRequest stringRequest;
	 DbUtils db;

	public StockManager(Context context){
		this.context = context;
	}
	
	public StockManager(Context context, Application myApp, Handler handler) {
		this.context = context;
		this.mQueue = Volley.newRequestQueue(context);
		this.myApplication = (MyApplication) myApp;
		this.handler = handler;
	}
	final int maxCount = 3;
	int currentCount = 0;
	/**
	 * 下载股票文件，保存到目录
	 */
	public void downloadStocksInfos(final SharedPreferences sharedPreferences,final String key) {
		final long stime = System.currentTimeMillis();
		stringRequest = new StringRequest(Statics.URL_STOCK,
				new Response.Listener<String>() {
					@Override
					public void onResponse(final String response) {
						try { 
							Log.v(TAG, response);
							if(response!=null){ 
								new Thread(new Runnable() {
									
									@Override
									public void run() {
										Log.d(TAG, "~~~~~~~~~~~thread 不执行~~~~~~~ ");
										String json;
										try {
											json = PullStockParser.parseXmlStocks(new ByteArrayInputStream(
													response.trim()
																.getBytes()));
											stockInfos = PullStockParser.parseToJson(json); 
											db = DbUtils.create(context, STOCKS_DBNAME); 
											deleteAll();
											Log.d(TAG, "~~~~~~response size 2= " + stockInfos.size());
											insertAll();
											Editor editor = sharedPreferences.edit();
											editor.putString(KEY_HASNEWEST, key); 
											editor.commit();
		//									findStocks("平安"); 
											Log.d(TAG, "总共花费时间：" + (System.currentTimeMillis() - stime) / 1000 + "s");
										} catch (Exception e) { 
											e.printStackTrace();
										}
										
									}
								}).start();
							}else{
								Log.d(TAG, "~~~~~~~~~~~thread 不执行~~22s~~~~~ ");
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
						
					}
				}, new Response.ErrorListener() {
					@Override
					public void onErrorResponse(VolleyError error) {
						Log.e("TAG", error.getMessage(), error);
						currentCount++;
						if(currentCount<maxCount){
//							downloadStocksInfos(sharedPreferences, key);
							Log.e("TAG", "try downloadStocksInfos again , count="+currentCount);
						}
						
					}
				}){
			
			@Override
			public RetryPolicy getRetryPolicy() { 
				RetryPolicy retryPolicy = new DefaultRetryPolicy(Statics.SOCKET_TIMEOUT, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);  
				return retryPolicy;  
			}
		};
		stringRequest.setCharset("utf-8");
		mQueue.add(stringRequest);
	}

	public void closeQueue() {
		if (stringRequest != null)
			mQueue.cancelAll(stringRequest);
	}

	public void getNewestStocks() {
		// 读取今天缓存数据
		// 没有，读取网络数据
		// 写本地缓存
		// 读取
		try {
			open();
			stockInfos = getDiskFileJson2List();
			if (stockInfos != null) {
				Log.e(TAG, "~~getNewestStocks~~~~~~" + stockInfos.size());
			} else {
				editDiskCache();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void open() throws IOException {
		File file = KouFuTools.getDiskCacheDir(context, STOCKS_FILENAME);
		if (!file.exists()) {
			file.mkdirs();
		}
		mDiskLruCache = DiskLruCache.open(
				KouFuTools.getDiskCacheDir(context, STOCKS_FILENAME),
				KouFuTools.getAppVersion(context), 1, DISK_CACHE_SIZE);
	}

	public void closeDiskCache() {
		try {
			mDiskLruCache.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void clearDiskCache() {
		try {
			mDiskLruCache.delete();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @Title: wirteStocksToCacheFile
	 * @Description: TODO(把数据写入到缓存文件)
	 * @param @param stocks
	 * @param @return 设定文件
	 * @return boolean 返回类型
	 * @throws
	 */
	public boolean wirteStocksToCacheFile(String stocks, OutputStream out) {
		// File file = KouFuTools.getDiskCacheDir(context, STOCKS_FILENAME);
		// RandomAccessFile raf = null;
		try {
			// raf = new RandomAccessFile(new
			// File(file.getPath()+File.separator+STOCKS_FILENAME), "rw");
			// // raf.seek(file.length());
			// raf.write(stocks.getBytes());
			out.write(stocks.getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			// try {
			// raf.close();
			// } catch (IOException e) {
			// e.printStackTrace();
			// }
		}
		return true;
	}

	public void editDiskCache() {
		try {
			String key = getCurrentKey();
			DiskLruCache.Editor editor = mDiskLruCache.edit(key);
			OutputStream outputStream = editor.newOutputStream(0);
			if (editor != null) {
//				downloadStocksInfos(editor, outputStream);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private String getCurrentKey() {
		return KouFuTools.hashKeyForDisk(DateFormat.format("yyyyMMdd",
				Calendar.getInstance()).toString());
	}

	public ArrayList<Stock> getDiskFileJson2List() {
		try {
			DiskLruCache.Snapshot snapShot = mDiskLruCache.get(getCurrentKey());
			if (snapShot != null) {
				// InputStream is = snapShot.getInputStream(0);
				String response = KouFuTools.inputStream2String(snapShot
						.getInputStream(0));
				Log.e(TAG, "~~getDiskFile~~" + response);
				ArrayList<Stock> datas = PullStockParser
						.parseToJson(response);
				return datas;
			} else {
				return null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	 
	/*******************************
	 * 数据库相关
	 * ******************************
	 */
	public ArrayList<Stock> getDBStocksList() {
		try {
			 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	public boolean insertAll(){
		try {
			if(stockInfos!=null && stockInfos.size()>0){
				if(db ==null){
					db = DbUtils.create(context,STOCKS_DBNAME);
				}
			 db.saveAll(stockInfos);
			}
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}finally{
			db.close();
		}
		return true;
	}
	public boolean deleteAll(){
		try { 
			if(db==null){
				db = DbUtils.create(context,STOCKS_DBNAME); 
			}
			 db.deleteAll(Stock.class);
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		
		return true;
	}
	
	public ArrayList<Stock> findStocks(String key){
		List<Stock> stocks = new ArrayList<Stock>();
		
		try {
			if(db==null){
				db = DbUtils.create(context,STOCKS_DBNAME); 
			}
			 db.configDebug(true); 
			 stocks =  db.findAll(Selector.from(Stock.class).where("name","like",key+"%").or("code","like",key+"%").or("queryCode","like",key+"%"));
//			 for(Stock stock:stocks){
//				 Log.w("Tt", "~~~code="+stock.code+",name="+stock.name+",qcode="+stock.queryCode);
//			 }
//			 Log.w("Tt", stocks.size()+"===1----");
			 
//			 stocks = db.findAll(Stock.class);
//			 Log.w("Tt", stocks.size()+"===----");
//			 for(Stock stock:stocks){
//				 //if(stock.name.contains("平"))
//				 Log.w("Tt", "~~~code="+stock.code+",name="+stock.name+",qcode="+stock.queryCode);
//			 }
		}catch(Exception e){
			e.printStackTrace(); 
		}
		return (ArrayList<Stock>) stocks;
	}
	
	public void getNetStocks(){
		SharedPreferences sharedPreferences = context.getSharedPreferences(STOCKS_FILENAME, Context.MODE_PRIVATE);
		String localKey = sharedPreferences.getString(KEY_HASNEWEST, "0");
		String currentKey = getCurrentKey();
//		Log.w(TAG, localKey+"~~~~~~"+currentKey);
		if(localKey.equals(currentKey)){
			//已经更新过了，不做网络下载，直接从数据库中获取
//			findStocks("平安");
		}else{
			currentCount = 0;
			downloadStocksInfos(sharedPreferences,currentKey); 
		}
	}
	
	public ArrayList<Map<String , String>> getSelectStock(String key){  
		ArrayList<Map<String , String>> map = new ArrayList<Map<String,String>>();
		ArrayList<Stock> stocks = findStocks(key);
		for(Stock stock:stocks){
			 Map<String , String> stockMap = new HashMap<String , String>();
			 stockMap.put("qcode", stock.queryCode);
			 stockMap.put("name", stock.name);
			 stockMap.put("text", stock.name+"("+stock.queryCode+")");
			 map.add(stockMap);
		}
		return map;
	}
	public void findAllLst(){
		List<Stock> stocks = new ArrayList<Stock>();
		
		try {
			if(db==null){ 
				db = DbUtils.create(context,STOCKS_DBNAME); 
			}
			db.deleteAll(Stock.class);
			 db.configDebug(true);  
//			 Stock s= new Stock();
//			 s.code = "001";
//			 s.name = "zhong hua ";
//			 stocks.add(s);
//			 s.code = "002";
//			 stocks.add(s);
//			 s.code = "003";
//			 stocks.add(s);
//			 db.saveAll(stocks);
//			 stocks =  db.findAll(Selector.from(Stock.class));
//			 Log.w("Tt", stocks.size()+"===1----");
//			 for(Stock stock:stocks){
//				 Log.w("Tt", "~~~code="+stock.code+",name="+stock.name+",qcode="+stock.queryCode);
//			 }
//			
			 
//			 stocks = db.findAll(Stock.class);
//			 Log.w("Tt", stocks.size()+"===-2---");
//			 for(Stock stock:stocks){
//				 //if(stock.name.contains("平"))
//				 Log.w("Tt", "~~~code="+stock.code+",name="+stock.name+",qcode="+stock.queryCode);
//			 }
		}catch(Exception e){
			e.printStackTrace(); 
		}
	}
}
